home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / stpdos12.arc / STEPDOS.ASM < prev    next >
Assembly Source File  |  1987-12-05  |  79KB  |  2,853 lines

  1.  
  2.         PAGE    60,132
  3.         TITLE   'Step DOS Calls'
  4.         NAME    STEPDOS
  5. ;
  6. ;       ***********************************************************
  7. ;       *                                                         *
  8. ;       *                   S  T  E  P  D  O  S                   *
  9. ;       *                                                         *
  10. ;       *                        Rev 1.2                          *
  11. ;       *                                                         *
  12. ;       *                      Nov 21, 1987                       *
  13. ;       *                                                         *
  14. ;       *                      Mike Parker                        *
  15. ;       *                 2374 Meadowpark Court                   *
  16. ;       *               Maryland Heights, MO 63043                *
  17. ;       *                                                         *
  18. ;       *                     CIS 70270,161                       *
  19. ;       *                                                         *
  20. ;       *  This program allows you to step through the execution  *
  21. ;       *  of another program by intercepting all calls to DOS    *
  22. ;       *  INT 21H. A window will pop up displaying all register  *
  23. ;       *  values and a short description of the DOS function     *
  24. ;       *  being called. Program execution will continue when     *
  25. ;       *  you press a key. You can optionally break again after  *
  26. ;       *  the DOS function completes so you can see the result   *
  27. ;       *  code in the AX register along with important flags.    *
  28. ;       *                                                         *
  29. ;       ***********************************************************
  30. ;
  31. ; Changes for version 1.1:
  32. ;     Made STEPDOS a COM file instead of EXE.
  33. ;     Implement arrow keys to reposition window.
  34. ;     Only keep as much memory as needed for STEPDOS instead of 64K.
  35. ;     Doesn't add <NULL> to command line string passed to target program.
  36. ;     Changed stack switching in 'New21'.
  37. ;     Recognize DOS switch character ('/') in command line.
  38. ;     Use 'FIND FIRST' function 4eh when searching for target program
  39. ;        instead of trying to do 'OPEN'.
  40. ;     Support monochrome cards.
  41. ;     Display window on screen even if target program changes video page.
  42. ;     Change 'Disp_09' code to stop display at '$' terminator.
  43. ;     Ver 1.0 did not return the IF bit in the flag register to the user's
  44. ;        original state.
  45. ;
  46. ; Changes for version 1.2:
  47. ;     Added window movement using HOME, PGUP, END and PGDN keys to
  48. ;        move to the four corners of the screen.
  49. ;     Display version string on top of window.
  50. ;
  51. ;
  52. ; To run, type STEPDOS <filename>
  53. ;  where <filename> is the full pathname of an EXE or COM file.
  54. ;
  55. ;
  56. TESTING    EQU    0
  57.  
  58. BG         EQU    10H               ; BG sets background color (10h = BLUE)
  59.  
  60. BLACK      EQU    00H + BG
  61. BLUE       EQU    01H + BG
  62. GREEN      EQU    02H + BG
  63. CYAN       EQU    03H + BG
  64. RED        EQU    04H + BG
  65. MAGENTA    EQU    05H + BG
  66. BROWN      EQU    06H + BG
  67. WHITE      EQU    07H + BG
  68. GRAY       EQU    08H + BG
  69. LTBLUE     EQU    09H + BG
  70. LTGREEN    EQU    0AH + BG
  71. LTCYAN     EQU    0BH + BG
  72. LTRED      EQU    0CH + BG
  73. LTMAGENTA  EQU    0DH + BG
  74. YELLOW     EQU    0EH + BG
  75. HIWHITE    EQU    0FH + BG
  76. ;
  77. CR         EQU    13
  78. LF         EQU    10
  79. BIGR       EQU    1352H             ; 'R' key
  80. SMALLR     EQU    1372H             ; 'r'
  81. BIGS       EQU    1F53H             ; 'S' key
  82. SMALLS     EQU    1F73H             ; 's'
  83. ESCAPE     EQU    011BH
  84. HOME       EQU    4700H
  85. UPARROW    EQU    4800H
  86. PGUP       EQU    4900H
  87. LEFTARROW  EQU    4B00H
  88. RIGHTARROW EQU    4D00H
  89. XEND       EQU    4F00H
  90. DOWNARROW  EQU    5000H
  91. PGDN       EQU    5100H
  92. ;
  93. BLANK      EQU    32
  94. BRDROW     EQU    205
  95. BRDCOL     EQU    186
  96. ULC        EQU    201
  97. URC        EQU    187
  98. LLC        EQU    200
  99. LRC        EQU    188
  100. ;
  101. REGBX      EQU    00                ; offsets on saved register stack
  102. REGCX      EQU    02
  103. REGDX      EQU    04
  104. REGDI      EQU    06
  105. REGSI      EQU    08
  106. REGBP      EQU    10
  107. REGES      EQU    12
  108. ;
  109. IF TESTING
  110. INT21OFF   EQU    0e0h*4            ; during testing an unused INT is used
  111. ELSE
  112. INT21OFF   EQU    21h*4
  113. ENDIF
  114.  
  115. Code    SEGMENT PUBLIC PARA 'CODE'
  116.  
  117.         ASSUME  CS:Code, DS:Code
  118.  
  119.         ORG     100h
  120. Main:                               ; starting point
  121.         cli
  122.         cld
  123.         mov     AX,CS
  124.         mov     SS,AX
  125.         mov     SP,OFFSET Pstack
  126.         mov     BX,DS               ; get difference between segments
  127.         sub     AX,BX               ;  so .EXE file can run during testing
  128. ;
  129.         mov     BX,OFFSET PRSIZE    ; program size in bytes
  130.         mov     CL,4
  131.         shr     BX,CL               ; convert it to paragraphs
  132.         add     BX,AX               ; add difference between segments
  133.         inc     BX                  ; make it next multiple of 16 bytes
  134.         mov     AH,4ah              ; modify memory block size
  135.         int     21h
  136.         sti
  137. ;
  138. ; Copy command line from PSP to local area
  139. ;
  140.         mov     AX,CS
  141.         mov     ES,AX               ; change ES to be local area
  142. ;
  143.         mov     SI,0080h
  144.         mov     CL,[SI]             ; get command line character count
  145.         or      CL,CL               ; zero char count in cmd line?
  146.         jnz     notzcl
  147.         mov     AX,CS               ; yes, display 'Usage' message
  148.         mov     DS,AX               ;  and exit
  149.         mov     DX,OFFSET Umsg
  150.         mov     AH,9
  151.         int     21h
  152.         jmp     exit
  153. notzcl:
  154.         xor     CH,CH
  155.         inc     SI
  156.         mov     DI,OFFSET PSPstr
  157. rep     movsb                       ; copy command line
  158.         xor     AL,AL
  159.         stosb                       ; <NULL> terminator at end
  160. ;
  161.         mov     BX,002ch
  162.         mov     BX,[BX]             ; get segment addr of environment from PSP
  163. ;
  164.         mov     AX,CS
  165.         mov     DS,AX               ; change DS to local area
  166.         mov     SegEnv,BX           ; save in EXEC control block
  167. ;
  168. ; Check equipment list to see if we have graphics or monochrome card
  169. ;
  170.         int     11h
  171.         and     AX,0030h            ; save video mode
  172.         mov     BX,0b000h
  173.         cmp     AX,0030h            ; monochrome?
  174.         jz      setcrd
  175.         mov     BX,0b800h           ; no, graphics card
  176. setcrd:
  177.         mov     Scrseg,BX           ; save base segment
  178. ;
  179. ; Calculate starting address on screen for window
  180. ;
  181.         mov     BX,OFFSET W1        ; window parameters
  182.         call    Window_Parms        ; calc start addr of window, wid and ht
  183. ;
  184. ; Do DOS call to allocate memory
  185. ;
  186.         mov     CL,4
  187.         shr     AX,CL               ; divide by 16 to get # paragraphs
  188.         inc     AX                  ; handle any remainder
  189.         mov     BX,AX
  190.         mov     AH,48h              ; 'allocate memory' DOS call
  191.         int     21h
  192.         mov     Winseg,AX           ; save returned segment
  193.         jnc     cpynam
  194.         mov     DX,OFFSET Memerr    ; ERROR - display string
  195.         mov     AH,9
  196.         int     21h
  197.         jmp     exit                ;  and terminate
  198. ;
  199. ; Copy target program name
  200. ;
  201. cpynam:
  202.         mov     AX,3700h            ; get DOS switch character
  203.         int     21h
  204.         mov     Sw_Char,DL
  205. ;
  206.         mov     SI,OFFSET PSPstr + 1
  207.         mov     DI,OFFSET Filename
  208.         xor     CX,CX               ; zero char count
  209. fnlp:
  210.         mov     AL,[SI]
  211.         cmp     AL,' '              ; look for <SP>
  212.         jz      fndn
  213.         cmp     AL,00               ;  or <NULL> terminator
  214.         jz      fndn
  215.         cmp     AL,Sw_Char          ;  or switch character ('/')
  216.         jz      fndn
  217.         movsb
  218.         inc     CX                  ; count number of filename char's
  219.         jmp     fnlp
  220. fndn:
  221.         or      CX,CX
  222.         jnz     gotfn
  223.         mov     DX,OFFSET Findmsg   ; error if zero filename length
  224.         mov     AH,9
  225.         int     21h
  226.         jmp     freemem
  227. gotfn:
  228.         xor     AL,AL
  229.         stosb
  230.         mov     FNsize,CX
  231. ;
  232. ; Copy command line string
  233. ; SI -> first parameter after filename
  234. ;
  235.         mov     DI,OFFSET CLstr + 1
  236.         xor     CX,CX               ; zero char count
  237. cllp:
  238.         cmp     BYTE PTR [SI],00    ; look for <NULL> terminator
  239.         jz      dncl
  240.         movsb
  241.         inc     CX                  ; count number of cmd line char's
  242.         jmp     cllp
  243. dncl:
  244.         mov     AL,CR               ; put <CR> past end
  245.         stosb
  246.         mov     CLstr,CL            ; store cmd line count
  247. ;
  248. ; Build EXEC control block
  249. ;
  250.         mov     SegCmd,OFFSET CLstr
  251.         mov     SegCmd+2,DS
  252.         mov     FCBptr1,OFFSET FCB1
  253.         mov     FCBptr1+2,DS
  254.         mov     FCBptr2,OFFSET FCB2
  255.         mov     FCBptr2+2,DS
  256. ;
  257. ; Parse first parameter
  258. ;
  259.         mov     SI,OFFSET CLstr + 1
  260.         mov     DI,OFFSET FCB1
  261.         mov     AL,01               ; scan past separators
  262.         mov     AH,29h
  263.         int     21h
  264. ;
  265. ; Parse second parameter
  266. ;
  267.         mov     DI,OFFSET FCB2
  268.         mov     AL,01               ; scan past separators
  269.         mov     AH,29h
  270.         int     21h
  271. ;
  272. ; Try to find target file
  273. ;
  274.         call    Find_File
  275.         jnc     redirect            ; jump if found it
  276. ;
  277. ; File not found, display msg and exit
  278. ;
  279.         mov     DI,OFFSET Filename
  280.         xor     AL,AL               ; find terminating <NULL>
  281.         mov     CX,0ffffh           ; there must be one in there somewhere
  282. repne   scasb
  283.         dec     DI
  284.         mov     AL,27h              ; closing quote
  285.         stosb
  286.         mov     AL,'$'              ; put string terminator for DOS function 09
  287.         stosb
  288. ;
  289.         mov     DX,OFFSET Findmsg   ; not found message
  290.         mov     AH,9
  291.         int     21h
  292. ;
  293.         mov     DX,OFFSET Filename  ; show filename we were looking for
  294.         mov     AH,9
  295.         int     21h
  296.         jmp     freemem
  297. ;
  298. ; Redirect INT 21h
  299. ;
  300. redirect:
  301.         push    ES
  302.         cli
  303.         mov     AX,0
  304.         mov     ES,AX
  305.         mov     AX,OFFSET New21
  306.         xchg    AX,ES:[INT21OFF]
  307.         mov     Save21,AX
  308.         mov     AX,CS
  309.         xchg    AX,ES:[INT21OFF+2]
  310.         mov     Save21+2,AX
  311.         sti
  312.         pop     ES
  313. ;
  314. ; Execute target program
  315. ;
  316.         mov     SP,OFFSET Tstack
  317.  
  318. IF TESTING
  319.         include test.asm
  320.         clc                         ; no error
  321. ELSE
  322.         mov     DX,OFFSET Filename
  323.         mov     BX,OFFSET Param_Block
  324.         mov     AH,4bh
  325.         mov     AL,0
  326.         int     21h
  327. ENDIF
  328. ;
  329.         cli
  330.         mov     AX,CS               ; restore segment registers
  331.         mov     DS,AX
  332.         mov     ES,AX
  333.         mov     SS,AX
  334.         mov     SP,OFFSET Pstack
  335.         jnc     execdn
  336. ;
  337. ; Failed to execute target program. Display message and quit
  338. ;
  339.         mov     DX,OFFSET Execmsg
  340.         mov     AH,9
  341.         int     21h
  342. ;
  343. ; Restore INT 21h vector
  344. ;
  345. execdn:
  346.         cli
  347.         mov     AX,0
  348.         mov     ES,AX
  349.         mov     AX,Save21
  350.         mov     ES:[INT21OFF],AX
  351.         mov     AX,Save21+2
  352.         mov     ES:[INT21OFF+2],AX
  353.         sti
  354. ;
  355. ; Free allocated memory from window save area
  356. ;
  357. freemem:
  358.         mov     ES,Winseg
  359.         mov     AH,49h
  360.         int     21h
  361. exit:
  362.         mov     AH,4ch              ; terminate process
  363.         mov     AL,00
  364.         int     21h                 ; won't return
  365.  
  366. ;
  367. ;
  368. ; Search for file. If no extention specified try both .COM and .EXE
  369. ;
  370. Find_File:
  371.         mov     DI,OFFSET Filename
  372.         mov     CX,FNsize           ; get program filename size
  373.         mov     AL,'.'
  374. repne   scasb                       ; check for '.' in target program filename
  375.         jz      fndext              ; jump if found extention
  376. ;
  377. ; No extention found, try appending '.COM'
  378. ;
  379.         mov     SI,OFFSET COMstr
  380.         mov     DI,OFFSET Filename
  381.         add     DI,FNsize
  382.         mov     CX,4
  383. rep     movsb
  384. ;
  385. ; See if the target program exists before we change the Int 21h vector
  386. ; and EXEC it.
  387. ;
  388.         mov     AH,4eh              ; find first filename
  389.         mov     CX,00               ; attribute code
  390.         mov     DX,OFFSET Filename
  391.         int     21h
  392.         jnc     fret                ; jump if file found
  393. ;
  394. ; FIND with '.COM' extention failed, try appending '.EXE'
  395. ;
  396.         mov     SI,OFFSET EXEstr
  397.         mov     DI,OFFSET Filename
  398.         add     DI,FNsize
  399.         mov     CX,4
  400. rep     movsb
  401. ;
  402. ; Try to find the '.EXE' version of the file
  403. ;
  404. fndext:
  405.         mov     AH,4eh
  406.         mov     CX,00               ; attribute code
  407.         mov     DX,OFFSET Filename
  408.         int     21h
  409. fret:
  410.         ret                         ; carry flag has error status
  411.  
  412. ;
  413. ; INT 21h will be redirected to here
  414. ;
  415. New21:
  416.         push    AX                  ; use USERS'S stack for first 3 words
  417.         push    DS
  418.         pushf                       ; push them but we don't need them here
  419. ;
  420.         cli
  421.         mov     AX,CS               ; now switch to internal stack
  422.         mov     DS,AX
  423.         mov     SSsave,SS
  424.         mov     SPsave,SP
  425.         mov     SS,AX
  426.         mov     SP,OFFSET Pstack
  427.         sti
  428. ;
  429.         push    ES
  430.         push    BP
  431.         push    SI
  432.         push    DI
  433.         push    DX
  434.         push    CX
  435.         push    BX
  436.         mov     BP,SP               ; save base pointer to display reg's
  437.         mov     ES,AX
  438.         mov     AL,Run_Flg
  439.         test    AL,0ffh             ; should we stop and display?
  440.         jz      norun               ; no, restore registers and leave
  441. ;
  442. ; Recover registers on USER'S stack
  443. ;
  444.         push    ES
  445.         les     BX,Ssave
  446.         mov     AX,ES:[BX+2]        ; get DS
  447.         mov     DSsave,AX
  448.         mov     AX,ES:[BX+4]        ; get AX
  449.         mov     AXsave,AX
  450.         mov     AX,ES:[BX+6]        ; get IP
  451.         mov     IPsave,AX
  452.         mov     AX,ES:[BX+8]        ; get CS
  453.         mov     CSsave,AX
  454.         mov     AX,ES:[BX+10]       ; get FLAGS on entry
  455.         mov     FLsave,AX
  456.         pop     ES
  457. ;
  458.         cld                         ; clear direction flag for string operations
  459.         mov     AL,Skip_Flg
  460.         test    AL,0ffh             ; skip certain functions?
  461.         jz      noskip              ; no, continue
  462.         mov     AX,AXsave           ; get USER's AX register with function code
  463.         cmp     AH,Skip_Typ         ; compare upper half to type to skip
  464.         jz      norun               ; don't want to break on this one again
  465.         mov     AL,00               ; skip flag was set but this is new
  466.         mov     Skip_Flg,AL         ;  function, so break from now on
  467. noskip:
  468.         call    Open_Window
  469.         call    Show_Regs
  470.         call    Show_Help
  471.         call    Disp_Text           ; Display description string of DOS function
  472. ;
  473.         call    Get_Key             ; wait for a key pressed
  474.         call    Disp_Key            ; dispatch to key handler
  475.         jc      noskip              ; if carry set, need to redisplay window
  476.         call    Close_Window
  477. norun:
  478.         pop     BX
  479.         pop     CX
  480.         pop     DX
  481.         pop     DI
  482.         pop     SI
  483.         pop     BP
  484.         pop     ES
  485.         cli
  486.         mov     SS,SSsave           ; switch back to user's stack
  487.         mov     SP,SPsave
  488. ;
  489.         mov     AX,FLsave           ; get original user's flags before INT 21h
  490.         push    AX                  ; sneak them into flag register
  491.         popf
  492. ;
  493.         pop     AX                  ; dummy pop to get flags off stack
  494.         pop     DS                  ; restore registers left on user's stack
  495.         pop     AX                  ; now get real AX
  496.  
  497. IFE TESTING
  498.         pushf
  499.         cli                         ; give interrupt code IF = 0 like normal
  500.         call    CS:[DWORD PTR Save21]
  501. ENDIF
  502.  
  503.         push    AX                  ; use USERS'S stack for first 3 words
  504.         push    DS
  505.         pushf                       ; they will get used this time
  506. ;
  507.         cli
  508.         mov     AX,CS               ; now switch to internal stack
  509.         mov     DS,AX
  510.         mov     SSsave,SS
  511.         mov     SPsave,SP
  512.         mov     SS,AX
  513.         mov     SP,OFFSET Pstack
  514.         sti
  515. ;
  516.         push    ES
  517.         push    BP
  518.         push    SI
  519.         push    DI
  520.         push    DX
  521.         push    CX
  522.         push    BX
  523.         mov     BP,SP               ; save base pointer to display reg's
  524.         mov     ES,AX
  525.         cld                         ; clear direction flag for string operations
  526. ;
  527. ; Recover registers on USER'S stack
  528. ;
  529.         push    ES
  530.         les     BX,Ssave
  531.         mov     AX,ES:[BX+0]        ; get FLAGS on exit
  532.         mov     FLsave,AX
  533.         mov     AX,ES:[BX+2]        ; get DS
  534.         mov     DSsave,AX
  535.         mov     AX,ES:[BX+4]        ; get AX
  536.         mov     AXsave,AX
  537.         mov     AX,ES:[BX+6]        ; get IP
  538.         mov     IPsave,AX
  539.         mov     AX,ES:[BX+8]        ; get CS
  540.         mov     CSsave,AX
  541.         pop     ES
  542. ;
  543.         xor     AL,AL
  544.         xchg    AL,Ret_Flg          ; read value and clear flag for next time
  545.         test    AL,0ffh             ; is flag set to display return value?
  546.         jz      nostop
  547. ;
  548.         call    Open_Window
  549.         call    Show_Regs
  550.         call    Disp_Ret            ; display return code in AX and flags
  551.         call    Get_Key             ; wait for a key pressed
  552.         call    Close_Window
  553. nostop:
  554.         pop     BX
  555.         pop     CX
  556.         pop     DX
  557.         pop     DI
  558.         pop     SI
  559.         pop     BP
  560.         pop     ES
  561.         cli
  562.         mov     SS,SSsave
  563.         mov     SP,SPsave
  564.         popf
  565.         pop     DS
  566.         pop     AX
  567.         retf    2
  568.  
  569. ;
  570. ; Display return code in AX, carry and zero flags
  571. ;
  572. Disp_Ret:
  573.         mov     DX,OFFSET RCStr
  574.         mov     DI,14
  575.         mov     AX,AXsave
  576.         call    OutWord
  577. ;
  578.         mov     DX,OFFSET CFStr
  579.         mov     DI,13
  580.         add     DI,DX
  581.         mov     AL,'0'
  582.         test    FLsave,0001         ; carry flag is least significant bit
  583.         jz      dcy
  584.         inc     AL                  ; carry was set so change to '1'
  585. dcy:
  586.         mov     [DI],AL             ; store it in string
  587.         add     CX,0015h            ; move cursor position
  588.         mov     BX,OFFSET W1
  589.         mov     AH,HIWHITE
  590.         call    WPrint
  591. ;
  592.         mov     DX,OFFSET ZFStr
  593.         mov     DI,12
  594.         add     DI,DX
  595.         mov     AL,'0'
  596.         test    FLsave,0040h        ; test zero flag
  597.         jz      dzf
  598.         inc     AL                  ; zero was set so change to '1'
  599. dzf:
  600.         mov     [DI],AL             ; store it in string
  601.         add     CX,0010h            ; move cursor position
  602.         mov     BX,OFFSET W1
  603.         mov     AH,HIWHITE
  604.         call    WPrint
  605. ;
  606.         mov     CX,0816h            ; display some help
  607.         mov     DX,OFFSET HlpStr5
  608.         mov     AH,YELLOW
  609.         call    WPrint
  610.         ret
  611.  
  612. ;
  613. ; Display register names in window
  614. ;
  615. Show_Regs:
  616.         mov     BX,OFFSET W1        ; window
  617.         mov     CX,0101h            ; cursor position - row, col
  618.         mov     DX,OFFSET RegStr1   ; message address
  619.         mov     AH,YELLOW           ; attribute
  620.         call    WPrint
  621. ;
  622.         add     CX,0100h            ; go down one row
  623.         mov     DX,OFFSET RegStr2
  624.         mov     AH,WHITE
  625.         call    WPrint
  626. ;
  627. ; Display register values
  628. ;
  629.         add     CX,0100h            ; down a row
  630.         mov     AX,AXsave           ; get user's AX
  631.         call    Whexwd              ; display hex word
  632. ;
  633.         push    BP                  ; save base pointer for string display
  634.         mov     DX,6                ; number of registers to show this loop
  635. disreg:
  636.         add     CX,0005h            ; move to next register field
  637.         mov     AX,[BP]
  638.         call    Whexwd              ; display hex word
  639.         add     BP,2
  640.         dec     DX
  641.         jnz     disreg
  642. ;
  643.         add     CX,0005h            ; move to next register field
  644.         mov     AX,SPsave           ; display SP
  645.         add     AX,6                ; add for 3 pushes we did
  646.         call    Whexwd
  647. ;
  648.         add     CX,0005h            ; move to next register field
  649.         mov     AX,DSsave           ; display DS
  650.         call    Whexwd
  651. ;
  652.         add     CX,0005h            ; display ES
  653.         mov     AX,[BP]
  654.         call    Whexwd
  655. ;
  656.         add     CX,0005h
  657.         mov     AX,SSsave           ; display SS
  658.         call    Whexwd
  659. ;
  660.         add     CX,0005h
  661.         mov     AX,CSsave           ; display CS
  662.         call    Whexwd
  663. ;
  664.         add     CX,0005h
  665.         mov     AX,IPsave           ; display IP
  666.         call    Whexwd
  667. ;
  668.         add     CX,0005h
  669.         mov     AX,FLsave           ; display FLAGS
  670.         call    Whexwd
  671.         pop     BP                  ; restore base pointer so display routines
  672.                                     ;  can use it
  673.         ret
  674.  
  675. ;
  676. ; Display HELP in Window
  677. ;
  678. Show_Help:
  679.         mov     CX,0802h            ; cursor position - row, col
  680.         mov     AH,LTRED            ; attribute for char
  681.         mov     AL,'S'
  682.         call    WChar               ; write one character with attribute
  683. ;
  684.         add     CX,0001h            ; add 1 to column number
  685.         mov     DX,OFFSET HlpStr1   ; message address
  686.         mov     AH,WHITE
  687.         call    WPrint
  688. ;
  689.         add     CX,0012h            ; move column number
  690.         mov     AH,LTRED            ; attribute for char
  691.         mov     AL,'R'
  692.         call    WChar               ; write one character with attribute
  693. ;
  694.         add     CX,0001h            ; move column number
  695.         mov     DX,OFFSET HlpStr2
  696.         mov     AH,WHITE
  697.         call    WPrint
  698. ;
  699.         add     CX,000ch
  700.         mov     AH,LTRED
  701.         mov     AL,'E'
  702.         call    WChar
  703. ;
  704.         add     CX,0001h
  705.         mov     AH,LTRED
  706.         mov     AL,'S'
  707.         call    WChar
  708. ;
  709.         add     CX,0001h
  710.         mov     AH,LTRED
  711.         mov     AL,'C'
  712.         call    WChar
  713. ;
  714.         add     CX,0001h
  715.         mov     DX,OFFSET HlpStr3
  716.         mov     AH,WHITE
  717.         call    WPrint
  718. ;
  719.         add     CX,000dh
  720.         mov     AH,LTRED
  721.         mov     AL,18h              ; up arrow
  722.         call    WChar
  723. ;
  724.         add     CX,0001h
  725.         mov     AH,LTRED
  726.         mov     AL,19h              ; down arrow
  727.         call    WChar
  728. ;
  729.         add     CX,0001h
  730.         mov     AH,LTRED
  731.         mov     AL,1bh              ; left arrow
  732.         call    WChar
  733. ;
  734.         add     CX,0001h
  735.         mov     AH,LTRED
  736.         mov     AL,1ah              ; right arrow
  737.         call    WChar
  738. ;
  739.         add     CX,0001h
  740.         mov     DX,OFFSET HlpStr4
  741.         mov     AH,WHITE
  742.         call    WPrint
  743.         ret
  744.  
  745. ;
  746. ; HextoDec converts a word in AX to an ASCII string
  747. ; Entry:
  748. ;      AX = word to convert
  749. ; Exit:
  750. ;      SI = Pointer to last two character of ASCII string in 'Astr'
  751. ;
  752. HextoDec:
  753.          push   AX
  754.          push   CX
  755.          push   DX
  756.          push   DI
  757. ;
  758.          mov    DI,OFFSET Astr
  759.          mov    CX,10000
  760.          xor    DX,DX
  761.          div    CX                  ; num / 10000
  762.          add    AL,'0'
  763.          stosb
  764.          mov    AX,DX
  765.          mov    CX,1000
  766.          xor    DX,DX
  767.          div    CX                  ; num / 1000
  768.          add    AL,'0'
  769.          stosb
  770.          mov    AX,DX
  771.          mov    CX,100
  772.          xor    DX,DX
  773.          div    CX                  ; num / 100
  774.          add    AL,'0'
  775.          stosb
  776.          mov    AX,DX
  777.          mov    CX,10
  778.          xor    DX,DX
  779.          div    CX                  ; num / 10
  780.          add    AL,'0'
  781.          stosb
  782.          mov    AX,DX
  783.          add    AL,'0'
  784.          stosb
  785.          xor    AL,AL               ; <NULL> terminator in string
  786.          stosb
  787.          sub    DI,3                ; back up pointer
  788.          mov    SI,DI
  789. ;
  790.          pop    DI
  791.          pop    DX
  792.          pop    CX
  793.          pop    AX
  794.          ret
  795.  
  796. ;
  797. ; Display the text description of the current DOS function code
  798. ;
  799. Disp_Text:
  800.         mov     AX,AXsave           ; get user's function code
  801.         cmp     AH,63h              ; is it in range?
  802.         jnb     not_fnd             ; jump if no
  803.         mov     DI,OFFSET FCtbl
  804.         mov     CX,LENFC / 6        ; number of entries
  805. cmpdt:
  806.         cmp     AH,[DI+1]           ; is this the right function?
  807.         jz      dtexec
  808.         add     DI,6                ; no, point to next
  809.         loop    cmpdt
  810. not_fnd:
  811.         mov     DX,OFFSET STRUN
  812.         call    Disp_Str
  813.         ret
  814.  
  815. dtexec:
  816.         mov     DX,[DI+2]           ; get pointer to string
  817.         call    [WORD PTR DI+4]     ; go to display routine
  818.         ret
  819.  
  820. ;
  821. ; Display string of DOS function code description
  822. ;
  823. ; Entry:
  824. ;       DX = pointer to string
  825. ;
  826. Disp_Str:
  827.         mov     CX,0501h
  828.         mov     BX,OFFSET W1
  829.         mov     AH,HIWHITE
  830.         call    WPrint
  831.         ret
  832.  
  833. ;
  834. ; Only one string must be inserted.
  835. ; It is pointed to by user's DS:DX.
  836. ; Entry:
  837. ;      DX = text string containing description of function call
  838. ;      DI = offset within local string (DX) to put user's (DS:DX)
  839. ;      CX = max length before you will hit right side of Window
  840. ;
  841. One_String:
  842.         add     DI,DX
  843.         push    DS
  844.         mov     DS,DSsave
  845.         mov     SI,[BP+REGDX]       ; get USER's DS:DX value
  846. rep     movsb                       ; copy user's memory to text string
  847.         pop     DS
  848.         call    Disp_Str
  849.         ret
  850.  
  851. ;
  852. ; Convert users's DS and DX to ASCII, imbed them in target string
  853. ; Entry:
  854. ;      DX = pointer to string
  855. ;      DI = offset where to put converted DS:DX
  856. ;
  857. OutDSDX:
  858.         add     DI,DX
  859.         mov     AX,DSsave           ; get user's DS
  860.         call    Shexwrd
  861.         inc     DI                  ; skip past ':'
  862.         mov     AX,[BP+REGDX]       ; get user's DX
  863.         call    Shexwrd
  864.         call    Disp_Str
  865.         ret
  866.  
  867. ;
  868. ; Convert word in AX to ASCII, imbed it in target string
  869. ; Entry:
  870. ;      AX = word to convert
  871. ;      DX = pointer to string
  872. ;      DI = offset where to put converted AX
  873. ;
  874. OutWord:
  875.         add     DI,DX
  876.         call    Shexwrd
  877.         call    Disp_Str
  878.         ret
  879.  
  880. ;
  881. ; Convert 'AL' to ASCII and imbed it in target string
  882. ; Entry:
  883. ;      DX = target string
  884. ;      DI = offset to put converted 'AL'
  885. ;      AL = value to convert
  886. ;
  887. OutByte:
  888.         add     DI,DX
  889.         call    Shexbyt
  890.         call    Disp_Str
  891.         ret
  892.  
  893. ;
  894. ; Routines to build string for display - some values need to be filled in
  895. ;
  896. ; Entry:
  897. ;       DX = pointer to string
  898. ;
  899. Disp_02:
  900. Disp_04:
  901. Disp_05:
  902.         mov     DI,DX
  903.         add     DI,22               ; offset this many into string
  904.         mov     AX,[BP+REGDX]       ; DL register has char to output
  905.         call    Shexbyt             ; convert it to ASCII
  906.         mov     [DI+8],AL           ; show hex byte
  907.         call    Disp_Str
  908.         ret
  909.  
  910. ;
  911. ; Direct Keyboard/Display I/O
  912. ;
  913. Disp_06:
  914.         call    Disp_Str
  915.         mov     AX,[BP+REGDX]       ; DL register has I/O type
  916.         mov     DX,OFFSET STR06I
  917.         cmp     AL,0ffh             ; input character?
  918.         jz      d06io
  919.         mov     DX,OFFSET STR02     ; no, output character in 'DL'
  920.         mov     DI,DX
  921.         add     DI,22               ; offset this many into string
  922.         call    Shexbyt             ; convert it to ASCII
  923.         mov     [DI+8],AL           ; show hex byte
  924. d06io:
  925.         add     CX,0015h
  926.         mov     BX,OFFSET W1
  927.         mov     AH,HIWHITE
  928.         call    WPrint
  929.         ret
  930.  
  931. ;
  932. ; Display String
  933. ; Entry:
  934. ;      DX = pointer to string
  935. ;
  936. Disp_09:
  937.         mov     DI,18               ; offset where (DS:DX) goes within string
  938.         add     DI,DX
  939.         mov     cx,52               ; max number of char's to fit in window
  940.         push    DS
  941.         mov     DS,DSsave
  942.         mov     SI,[BP+REGDX]       ; get USER's DS:DX value
  943. rep     movsb                       ; copy user's memory to text string
  944.         pop     DS
  945.         mov     DI,18
  946.         add     DI,DX
  947.         mov     CX,52               ; max # of char's we care about
  948.         mov     AL,'$'              ; search for '$' terminator
  949. repne   scasb
  950.         jnz     d09                 ; jump if '$' not in first 52 chars
  951.         dec     DI
  952.         mov     BYTE PTR [DI],00    ; replace with <NULL> terminator
  953. d09:
  954.         call    Disp_Str
  955.         ret
  956.  
  957. Disp_39:
  958. Disp_3a:
  959. Disp_3b:
  960. Disp_3c:
  961. Disp_3d:
  962. Disp_41:
  963. Disp_5a:
  964. Disp_5b:
  965.         mov     DI,18               ; offset where (DS:DX) goes within string
  966.         mov     cx,52               ; max number of char's to fit in window
  967.         call    One_String
  968.         ret
  969.  
  970. Disp_0a:
  971. Disp_23:
  972.         mov     DI,27
  973.         call    OutDSDX
  974.         ret
  975.  
  976. ;
  977. ; Clear Keyboard and Do Function
  978. ;
  979. Disp_0c:
  980.         mov     DI,31
  981.         mov     AX,AXsave           ; AL register has function number
  982.         call    OutByte
  983.         ret
  984.  
  985. ;
  986. ; Select Disk
  987. ;
  988. Disp_0e:
  989.         mov     DI,12
  990.         mov     AX,[BP+REGDX]       ; DL register has char to output
  991.         call    OutByte
  992.         ret
  993.  
  994. ;
  995. ; Open File Using FCB
  996. ;
  997. Disp_0f:
  998.         mov     DI,23
  999.         call    OutDSDX
  1000.         ret
  1001.  
  1002. ;
  1003. ; Close File Using FCB
  1004. ;
  1005. Disp_10:
  1006.         mov     DI,24
  1007.         call    OutDSDX
  1008.         ret
  1009.  
  1010. ;
  1011. ; Search For First Matching File Using FCB
  1012. ;
  1013. Disp_11:
  1014.         mov     DI,44
  1015.         call    OutDSDX
  1016.         ret
  1017.  
  1018. ;
  1019. ; Search For Next Matching File Using FCB
  1020. ;
  1021. Disp_12:
  1022.         mov     DI,43
  1023.         call    OutDSDX
  1024.         ret
  1025.  
  1026. ;
  1027. ; Delete File Using FCB
  1028. ; Create File Using FCB
  1029. ; Rename File Using FCB
  1030. ;
  1031. Disp_13:
  1032. Disp_16:
  1033. Disp_17:
  1034.         mov     DI,25
  1035.         call    OutDSDX
  1036.         ret
  1037.  
  1038. ;
  1039. ; Read Sequential File Record Using FCB
  1040. ;
  1041. Disp_14:
  1042.         mov     DI,41
  1043.         call    OutDSDX
  1044.         ret
  1045.  
  1046. ;
  1047. ; Write Sequential File Record Using FCB
  1048. ;
  1049. Disp_15:
  1050.         mov     DI,42
  1051.         call    OutDSDX
  1052.         ret
  1053.  
  1054. ;
  1055. ; Set Disk Transfer Address
  1056. ;
  1057. Disp_1a:
  1058.         mov     DI,29
  1059.         call    OutDSDX
  1060.         ret
  1061.  
  1062. ;
  1063. ; Get FAT Information For Drive
  1064. ;
  1065. Disp_1c:
  1066.         mov     DI,30
  1067.         mov     AX,[BP+REGDX]       ; DL register has drive number
  1068.         call    OutByte
  1069.         ret
  1070.  
  1071.  
  1072. ;
  1073. ; Read Random File Record Using FCB
  1074. ; Set Random Record Field Using FCB
  1075. ;
  1076. Disp_21:
  1077. Disp_24:
  1078.         mov     DI,37
  1079.         call    OutDSDX
  1080.         ret
  1081.  
  1082. ;
  1083. ; Write Random File Record Using FCB
  1084. ;
  1085. Disp_22:
  1086.         mov     DI,38
  1087.         call    OutDSDX
  1088.         ret
  1089.  
  1090. ;
  1091. ; Set Interrupt Vector
  1092. ;
  1093. Disp_25:
  1094.         mov     DI,DX
  1095.         add     DI,21
  1096.         mov     AX,AXsave           ; AL has interrupt vector number
  1097.         call    Shexbyt
  1098.         mov     DI,28
  1099.         call    OutDSDX
  1100.         ret
  1101.  
  1102. ;
  1103. ; Create New Program Segment
  1104. ;
  1105. Disp_26:
  1106.         mov     DI,38
  1107.         mov     AX,[BP+REGDX]       ; get user's DX
  1108.         call    OutWord
  1109.         ret
  1110.  
  1111. ;
  1112. ; Read Random File Records
  1113. ;
  1114. Disp_27:
  1115.         mov     DI,DX
  1116.         add     DI,5
  1117.         mov     AX,[BP+REGCX]       ; CX register has record count
  1118.         call    Shexwrd
  1119.         mov     DI,44
  1120.         call    OutDSDX
  1121.         ret
  1122.  
  1123. ;
  1124. ; Write Random File Records
  1125. ;
  1126. Disp_28:
  1127.         mov     DI,DX
  1128.         add     DI,6
  1129.         mov     AX,[BP+REGCX]       ; CX register has record count
  1130.         call    Shexwrd
  1131.         mov     DI,45
  1132.         call    OutDSDX
  1133.         ret
  1134. ;
  1135. ; Parse Filename
  1136. ;
  1137. Disp_29:
  1138.         mov     DI,18               ; offset where (DS:SI) goes within string
  1139.         mov     cx,52               ; max number of char's to fit in window
  1140.         add     DI,DX
  1141.         push    DI                  ; save for scan later
  1142.         push    DS
  1143.         mov     DS,DSsave
  1144.         mov     SI,[BP+REGSI]       ; get USER's DS:SI value
  1145. rep     movsb                       ; copy user's memory to text string
  1146.         pop     DS
  1147. ;
  1148. ; look for <CR> in string and put <NULL> terminator there
  1149. ;
  1150.         pop     DI
  1151.         mov     AL,CR
  1152.         mov     cx,52
  1153. repne   scasb
  1154.         jnz     dpf
  1155.         dec     DI
  1156.         xor     AL,AL
  1157.         mov     [DI],AL
  1158. dpf:
  1159.         call    Disp_Str
  1160.         ret
  1161.  
  1162. ;
  1163. ; Set Date
  1164. ;
  1165. Disp_2b:
  1166.         mov     DI,DX
  1167.         add     DI,22
  1168.         mov     AX,[BP+REGDX]       ; DX register has month/day
  1169.         mov     AL,AH
  1170.         xor     AH,AH
  1171.         call    HextoDec            ; convert month
  1172.         movsb
  1173.         movsb
  1174.         inc     DI                  ; skip past '/'
  1175.         mov     AX,[BP+REGDX]
  1176.         xor     AH,AH
  1177.         call    HextoDec            ; convert day
  1178.         movsb
  1179.         movsb
  1180.         inc     DI                  ; skip past '/'
  1181.         mov     AX,[BP+REGCX]
  1182.         call    HextoDec            ; convert year
  1183.         movsb
  1184.         movsb
  1185.         call    Disp_Str
  1186.         ret
  1187.  
  1188. ;
  1189. ; Set Time
  1190. ;
  1191. Disp_2d:
  1192.         mov     DI,DX
  1193.         add     DI,33
  1194.         mov     AX,[BP+REGCX]       ; CX register has hours/minutes
  1195.         mov     AL,AH
  1196.         xor     AH,AH
  1197.         call    HextoDec            ; convert hours
  1198.         movsb
  1199.         movsb
  1200.         inc     DI                  ; skip past ':'
  1201.         mov     AX,[BP+REGCX]
  1202.         xor     AH,AH
  1203.         call    HextoDec            ; convert minutes
  1204.         movsb
  1205.         movsb
  1206.         inc     DI                  ; skip past ':'
  1207.         mov     AX,[BP+REGDX]       ; DX has seconds/hundreds of seconds
  1208.         mov     AL,AH
  1209.         xor     AH,AH
  1210.         call    HextoDec            ; convert seconds
  1211.         movsb
  1212.         movsb
  1213.         inc     DI                  ; skip past ':'
  1214.         mov     AX,[BP+REGDX]
  1215.         xor     AH,AH
  1216.         call    HextoDec            ; convert hundreds
  1217.         movsb
  1218.         movsb
  1219.         call    Disp_Str
  1220.         ret
  1221.  
  1222. ;
  1223. ; Set Disk Write Verification
  1224. ;
  1225. Disp_2e:
  1226.         mov     DI,DX
  1227.         add     DI,28
  1228.         mov     AX,AXsave           ; AL register has verify switch
  1229.         mov     SI,OFFSET OFFstr
  1230.         cmp     AL,00               ; AL = 0 means OFF
  1231.         jz      verptr
  1232.         mov     SI,OFFSET ONstr
  1233.         cmp     AL,01               ; AL = 1 means ON
  1234.         jz      verptr
  1235.         mov     SI,OFFSET Blanks3   ; unknown code
  1236. verptr:
  1237.         mov     CX,3
  1238. rep     movsb
  1239.         call    Disp_Str
  1240.         ret
  1241.  
  1242. ;
  1243. ; Get/Set Control-Break Status
  1244. ;
  1245. Disp_33:
  1246.         mov     AX,AXsave           ; AL register has get/set switch
  1247.         cmp     AL,01               ; AL = 1 for SET
  1248.         jz      setcbs
  1249.         cmp     AL,00               ; AL = 0 for GET
  1250.         jnz     unk33               ; jump if unknown code
  1251.         mov     DX,OFFSET STR33G
  1252. unk33:
  1253.         call    Disp_Str
  1254.         ret
  1255.  
  1256. setcbs:
  1257.         mov     DX,OFFSET STR33S    ; point to 'SET' string
  1258.         mov     DI,DX
  1259.         add     DI,25
  1260.         mov     AX,[BP+REGDX]       ; DL has set code
  1261.         mov     SI,OFFSET OFFstr
  1262.         cmp     AL,00               ; AL = 00 means OFF
  1263.         jz      gscbs
  1264.         mov     SI,OFFSET ONstr
  1265.         cmp     AL,01               ; AL = 01 means ON
  1266.         jz      gscbs
  1267.         mov     SI,OFFSET Blanks3
  1268. gscbs:
  1269.         mov     CX,3
  1270. rep     movsb
  1271.         call    Disp_Str
  1272.         ret
  1273.  
  1274. ;
  1275. ; Get Interrupt Vector
  1276. ;
  1277. Disp_35:
  1278.         mov     DI,21
  1279.         mov     AX,AXsave           ; AL has interrupt vector number
  1280.         call    OutByte
  1281.         ret
  1282.  
  1283. ;
  1284. ; Get Disk Free Space On Drive
  1285. ;
  1286. Disp_36:
  1287.         mov     DI,29
  1288.         mov     AX,[BP+REGDX]       ; DL register has drive code
  1289.         call    OutByte
  1290.         ret
  1291.  
  1292. ;
  1293. ; Close File Handle
  1294. ;
  1295. Disp_3e:
  1296.         mov     DI,18
  1297.         mov     AX,[BP+REGBX]       ; BX register has file handle
  1298.         call    OutWord
  1299.         ret
  1300.  
  1301. ;
  1302. ; Duplicate File Handle
  1303. ;
  1304. Disp_45:
  1305.         mov     DI,22
  1306.         mov     AX,[BP+REGBX]       ; BX register has file handle
  1307.         call    OutWord
  1308.         ret
  1309.  
  1310. ;
  1311. ; Read From File or Device
  1312. ;
  1313. Disp_3f:
  1314.         mov     DI,DX
  1315.         add     DI,5
  1316.         mov     AX,[BP+REGCX]       ; CX has number of bytes to read
  1317.         call    Shexwrd
  1318.         mov     DI,37
  1319.         mov     AX,[BP+REGBX]       ; BX has file handle
  1320.         call    OutWord
  1321.         ret
  1322.  
  1323. ;
  1324. ; Write To File or Device
  1325. ;
  1326. Disp_40:
  1327.         mov     DI,DX
  1328.         add     DI,6
  1329.         mov     AX,[BP+REGCX]       ; CX has number of bytes to read
  1330.         call    Shexwrd
  1331.         mov     DI,36
  1332.         mov     AX,[BP+REGBX]       ; BX has file handle
  1333.         call    OutWord
  1334.         ret
  1335.  
  1336. ;
  1337. ; Move File Pointer
  1338. ;
  1339. Disp_42:
  1340.         mov     DI,DX
  1341.         add     DI,17
  1342.         mov     AX,[BP+REGBX]       ; BX register has file handle
  1343.         call    Shexwrd
  1344.         add     DI,13
  1345.         mov     AX,[BP+REGCX]       ; CX has upper half of offset
  1346.         call    Shexwrd
  1347.         inc     DI                  ; skip past ':'
  1348.         mov     AX,[BP+REGDX]       ; CX has lower half of offset
  1349.         call    Shexwrd
  1350.         add     DI,7
  1351.         mov     AX,AXsave           ; AL has method code
  1352.         mov     SI,OFFSET BOFstr
  1353.         cmp     AL,00               ; beginning of file?
  1354.         jz      mvptr
  1355.         mov     SI,OFFSET CURstr
  1356.         cmp     AL,01               ; current location?
  1357.         jz      mvptr
  1358.         mov     SI,OFFSET EOFstr
  1359.         cmp     AL,02               ; end of file?
  1360.         jz      mvptr
  1361.         mov     SI,OFFSET Blanks17  ; unknown
  1362. mvptr:
  1363.         mov     cx,17               ; string length
  1364. rep     movsb
  1365.         call    Disp_Str
  1366.         ret
  1367.  
  1368. ;
  1369. ; Get/Set file attributes
  1370. ;
  1371. Disp_43:
  1372.         mov     AX,AXsave           ; user's AX has get/set flag
  1373.         cmp     AL,00               ; 'get' code?
  1374.         jz      fgptr
  1375.         cmp     AL,01               ; 'set' code?
  1376.         jz      fsptr
  1377.         call    Disp_Str            ; unknown code
  1378.         ret
  1379. fgptr:
  1380.         mov     DX,OFFSET STR43G    ; point to GET string
  1381.         jmp     SHORT faptr
  1382. ;
  1383. fsptr:
  1384.         mov     DX,OFFSET STR43S    ; point to SET string
  1385. faptr:
  1386.         mov     DI,18
  1387.         mov     cx,52               ; max number of char's to fit in window
  1388.         call    One_String
  1389.         ret
  1390.  
  1391. ;
  1392. ; I/O Control For Devices
  1393. ;
  1394. Disp_44:
  1395.         mov     AX,AXsave
  1396.         cmp     AL,00
  1397.         jz      jd440
  1398.         cmp     AL,01
  1399.         jz      jd441
  1400.         cmp     AL,02
  1401.         jz      jd442
  1402.         cmp     AL,03
  1403.         jz      jd443
  1404.         cmp     AL,04
  1405.         jz      jd444
  1406.         cmp     AL,05
  1407.         jz      jd445
  1408.         cmp     AL,06
  1409.         jz      jd446
  1410.         cmp     AL,07
  1411.         jz      jd447
  1412.         cmp     AL,08
  1413.         jz      jd448
  1414.         cmp     AL,11
  1415.         jz      jd4411
  1416.         call    Disp_Str            ; unknown code
  1417.         ret
  1418.  
  1419. jd440:  jmp     d440
  1420. jd441:  jmp     d441
  1421. jd442:  jmp     d442
  1422. jd443:  jmp     d443
  1423. jd444:  jmp     d444
  1424. jd445:  jmp     d445
  1425. jd446:  jmp     d446
  1426. jd447:  jmp     d447
  1427. jd448:  jmp     d448
  1428. jd4411: jmp     d4411
  1429.  
  1430. d440:
  1431.         mov     DX,OFFSET STR440    ; Get Info For Device
  1432.         mov     DI,20
  1433.         mov     AX,[BP+REGBX]       ; BX has file handle
  1434.         call    OutWord
  1435.         ret
  1436. ;
  1437. d441:
  1438.         mov     DX,OFFSET STR441    ; Set Info For Device
  1439.         mov     DI,DX
  1440.         add     DI,20
  1441.         mov     AX,[BP+REGBX]       ; BX has file handle
  1442.         call    Shexwrd
  1443.         mov     DI,29
  1444.         mov     AX,[BP+REGDX]       ; DX has device information
  1445.         call    OutWord
  1446.         ret
  1447. ;
  1448. d442:
  1449.         mov     DX,OFFSET STR442    ; Read From Drive Control Channel
  1450.         mov     DI,DX
  1451.         add     DI,5
  1452.         mov     AX,[BP+REGCX]       ; CX has byte count
  1453.         call    Shexwrd
  1454.         mov     DI,52
  1455.         mov     AX,[BP+REGBX]       ; BX has file handle
  1456.         call    OutWord
  1457.         ret
  1458. ;
  1459. d443:
  1460.         mov     DX,OFFSET STR443    ; Write To Drive Control Channel
  1461.         mov     DI,DX
  1462.         add     DI,6
  1463.         mov     AX,[BP+REGCX]       ; CX has byte count
  1464.         call    Shexwrd
  1465.         mov     DI,51
  1466.         mov     AX,[BP+REGBX]       ; BX has file handle
  1467.         call    OutWord
  1468.         ret
  1469. ;
  1470. d444:
  1471.         mov     DX,OFFSET STR444    ; Read From Control Channel of Drive
  1472.         mov     DI,DX
  1473.         add     DI,5
  1474.         mov     AX,[BP+REGCX]       ; CX has byte count
  1475.         call    Shexwrd
  1476.         mov     DI,47
  1477.         mov     AX,[BP+REGBX]       ; BL has drive
  1478.         call    OutByte
  1479.         ret
  1480. ;
  1481. d445:
  1482.         mov     DX,OFFSET STR445    ; Write To Control Channel of Drive
  1483.         mov     DI,DX
  1484.         add     DI,6
  1485.         mov     AX,[BP+REGCX]       ; CX has byte count
  1486.         call    Shexwrd
  1487.         mov     DI,46
  1488.         mov     AX,[BP+REGBX]       ; BL has drive
  1489.         call    OutByte
  1490.         ret
  1491. ;
  1492. d446:
  1493.         mov     DX,OFFSET STR446    ; Get Input Status of Device
  1494.         mov     DI,27
  1495.         mov     AX,[BP+REGBX]       ; BX has file handle
  1496.         call    OutWord
  1497.         ret
  1498. ;
  1499. d447:
  1500.         mov     DX,OFFSET STR447    ; Get Output Status of Device
  1501.         mov     DI,28
  1502.         mov     AX,[BP+REGBX]       ; BX has file handle
  1503.         call    OutWord
  1504.         ret
  1505. ;
  1506. d448:
  1507.         mov     DX,OFFSET STR448    ; Report Whether Device Has Removable Media
  1508.         mov     DI,22
  1509.         mov     AX,[BP+REGBX]       ; BX has file handle
  1510.         call    OutWord
  1511.         ret
  1512. ;
  1513. d4411:
  1514.         mov     DX,OFFSET STR4411   ; Set Retries For Device
  1515.         mov     DI,DX
  1516.         add     DI,23
  1517.         mov     AX,[BP+REGBX]       ; BX has file handle
  1518.         call    Shexwrd
  1519.         add     DI,5
  1520.         mov     AX,[BP+REGDX]       ; DX has retry count
  1521.         call    Shexwrd
  1522.         mov     DI,55
  1523.         mov     AX,[BP+REGCX]       ; CX has interval between tries
  1524.         call    OutWord
  1525.         ret
  1526.  
  1527. ;
  1528. ; Force Duplication of Handle
  1529. ;
  1530. Disp_46:
  1531.         mov     DI,DX
  1532.         add     DI,28
  1533.         mov     AX,[BP+REGBX]       ; BX has the existing file handle
  1534.         call    Shexwrd
  1535.         mov     DI,37
  1536.         mov     AX,[BP+REGCX]       ; CX has the second file handle
  1537.         call    OutWord
  1538.         ret
  1539.  
  1540. ;
  1541. ; Get Current Directory
  1542. ;
  1543. Disp_47:
  1544.         mov     DI,DX
  1545.         add     DI,31
  1546.         mov     AX,[BP+REGDX]       ; DL register has drive code
  1547.         call    Shexbyt
  1548.         add     DI,7
  1549.         mov     AX,DSsave
  1550.         call    Shexwrd
  1551.         inc     DI                  ; skip ':'
  1552.         mov     AX,[BP+REGSI]       ; get USER's DS:SI value
  1553.         call    Shexwrd
  1554.         call    Disp_Str
  1555.         ret
  1556.  
  1557. ;
  1558. ; Allocate Memory
  1559. ;
  1560. Disp_48:
  1561.         mov     DI,9
  1562.         mov     AX,[BP+REGBX]       ; BX has the memory requested in paragraphs
  1563.         call    OutWord
  1564.         ret
  1565.  
  1566. ;
  1567. ; Free Allocated Memory
  1568. ;
  1569. Disp_49:
  1570.         mov     DI,33
  1571.         mov     AX,[BP+REGES]       ; ES has the segment address
  1572.         call    OutWord
  1573.         ret
  1574.  
  1575. ;
  1576. ; Modify Memory Block
  1577. ;
  1578. Disp_4a:
  1579.         mov     DI,DX
  1580.         add     DI,31
  1581.         mov     AX,[BP+REGES]       ; ES has the segment address
  1582.         call    Shexwrd
  1583.         mov     DI,43
  1584.         mov     AX,[BP+REGBX]       ; BX has size in paragraphs
  1585.         call    OutWord
  1586.         ret
  1587.  
  1588. ;
  1589. ; Load or Exececute Program
  1590. ; Find First Matching File
  1591. ;
  1592. Disp_4b:
  1593. Disp_4e:
  1594.         mov     DI,29               ; offset where (DS:DX) goes within string
  1595.         mov     cx,41               ; max number of char's to fit in window
  1596.         call    One_String
  1597.         ret
  1598.  
  1599. ;
  1600. ; Terminate Process with Return Code
  1601. ;
  1602. Disp_4c:
  1603.         mov     DI,35
  1604.         mov     AX,Axsave           ; AL register return code
  1605.         call    OutByte
  1606.         ret
  1607.  
  1608. ;
  1609. ; Rename File
  1610. ;
  1611. Disp_56:
  1612.         mov     DI,29
  1613.         mov     cx,41
  1614.         call    One_String          ; display 'old' name
  1615. ;
  1616.         mov     DX,OFFSET STR56N
  1617.         mov     DI,DX
  1618.         add     DI,29
  1619.         push    DS
  1620.         mov     DS,[BP+REGES]
  1621.         mov     SI,[BP+REGDI]       ; get USER's ES:DI value
  1622.         mov     cx,41               ;  to display 'new' name
  1623. rep     movsb
  1624.         pop     DS
  1625.         mov     CX,0601h
  1626.         mov     BX,OFFSET W1
  1627.         mov     AH,HIWHITE
  1628.         call    WPrint
  1629.         ret
  1630.  
  1631. ;
  1632. ; Get Date and Time of File
  1633. ;
  1634. Disp_57:
  1635.         mov     AX,AXsave           ; user's AL has get/set indicator
  1636.         cmp     AL,00               ; is it GET?
  1637.         jz      gdtptr
  1638.         cmp     AL,01               ; is it SET?
  1639.         jz      sdtptr
  1640.         mov     DI,37               ; unknown function
  1641.         mov     AX,[BP+REGBX]       ; file handle
  1642.         call    OutWord
  1643.         ret
  1644. gdtptr:
  1645.         mov     DX,OFFSET STR57G
  1646.         jmp     SHORT ddtptr
  1647. ;
  1648. sdtptr:
  1649.         mov     DX,OFFSET STR57S
  1650. ddtptr:
  1651.         mov     DI,33
  1652.         mov     AX,[BP+REGBX]       ; BX register has file handle
  1653.         call    OutWord
  1654.         ret
  1655.  
  1656. ;
  1657. ; Lock/Unlock File
  1658. ;
  1659. Disp_5c:
  1660.         mov     AX,AXsave
  1661.         cmp     AL,00               ; 0 = Lock
  1662.         jz      dlck
  1663.         cmp     AL,01               ; 1 = Unlock
  1664.         jz      dunlck
  1665.         mov     DI,17
  1666.         mov     AX,[BP+REGBX]       ; BX has file handle
  1667.         call    OutWord
  1668.         ret
  1669. ;
  1670. dlck:
  1671.         mov     DX,OFFSET STR5c0
  1672.         mov     DI,10
  1673.         mov     AX,[BP+REGBX]
  1674.         call    OutWord
  1675.         ret
  1676. ;
  1677. dunlck:
  1678.         mov     DX,OFFSET STR5c1
  1679.         mov     DI,12
  1680.         mov     AX,[BP+REGBX]
  1681.         call    OutWord
  1682.         ret
  1683.  
  1684.  
  1685. ;
  1686. ; Table of function codes.
  1687. ; (1st) word is DOS function code (AH),
  1688. ; (2nd) word is pointer to string to display,
  1689. ; (3rd) word is subroutine address to handle display of this type function.
  1690. ;
  1691. FCtbl:
  1692.         dw      0000h, STR00, Disp_Str
  1693.         dw      0100h, STR01, Disp_Str
  1694.         dw      0200h, STR02, Disp_02
  1695.         dw      0300h, STR03, Disp_Str
  1696.         dw      0400h, STR04, Disp_04
  1697.         dw      0500h, STR05, Disp_05
  1698.         dw      0600h, STR06, Disp_06
  1699.         dw      0700h, STR07, Disp_Str
  1700.         dw      0800h, STR08, Disp_Str
  1701.         dw      0900h, STR09, Disp_09
  1702.         dw      0a00h, STR0a, Disp_0a
  1703.         dw      0b00h, STR0b, Disp_Str
  1704.         dw      0c00h, STR0c, Disp_0c
  1705.         dw      0d00h, STR0d, Disp_Str
  1706.         dw      0e00h, STR0e, Disp_0e
  1707.         dw      0f00h, STR0f, Disp_0f
  1708.         dw      1000h, STR10, Disp_10
  1709.         dw      1100h, STR11, Disp_11
  1710.         dw      1200h, STR12, Disp_12
  1711.         dw      1300h, STR13, Disp_13
  1712.         dw      1400h, STR14, Disp_14
  1713.         dw      1500h, STR15, Disp_15
  1714.         dw      1600h, STR16, Disp_16
  1715.         dw      1700h, STR17, Disp_17
  1716.         dw      1800h, STRUN, Disp_Str
  1717.         dw      1900h, STR19, Disp_Str
  1718.         dw      1a00h, STR1a, Disp_1a
  1719.         dw      1b00h, STR1b, Disp_Str
  1720.         dw      1c00h, STR1c, Disp_1c
  1721.         dw      1d00h, STRUN, Disp_Str
  1722.         dw      1e00h, STRUN, Disp_Str
  1723.         dw      1f00h, STRUN, Disp_Str
  1724.         dw      2000h, STRUN, Disp_Str
  1725.         dw      2100h, STR21, Disp_21
  1726.         dw      2200h, STR22, Disp_22
  1727.         dw      2300h, STR23, Disp_23
  1728.         dw      2400h, STR24, Disp_24
  1729.         dw      2500h, STR25, Disp_25
  1730.         dw      2600h, STR26, Disp_26
  1731.         dw      2700h, STR27, Disp_27
  1732.         dw      2800h, STR28, Disp_28
  1733.         dw      2900h, STR29, Disp_29
  1734.         dw      2a00h, STR2a, Disp_Str
  1735.         dw      2b00h, STR2b, Disp_2b
  1736.         dw      2c00h, STR2c, Disp_Str
  1737.         dw      2d00h, STR2d, Disp_2d
  1738.         dw      2e00h, STR2e, Disp_2e
  1739.         dw      2f00h, STR2f, Disp_Str
  1740.         dw      3000h, STR30, Disp_Str
  1741.         dw      3100h, STR31, Disp_Str
  1742.         dw      3200h, STRUN, Disp_Str
  1743.         dw      3300h, STR33, Disp_33
  1744.         dw      3400h, STRUN, Disp_Str
  1745.         dw      3500h, STR35, Disp_35
  1746.         dw      3600h, STR36, Disp_36
  1747.         dw      3700h, STR37, Disp_Str
  1748.         dw      3800h, STR38, Disp_Str
  1749.         dw      3900h, STR39, Disp_39
  1750.         dw      3a00h, STR3a, Disp_3a
  1751.         dw      3b00h, STR3b, Disp_3b
  1752.         dw      3c00h, STR3c, Disp_3c
  1753.         dw      3d00h, STR3d, Disp_3d
  1754.         dw      3e00h, STR3e, Disp_3e
  1755.         dw      3f00h, STR3f, Disp_3f
  1756.         dw      4000h, STR40, Disp_40
  1757.         dw      4100h, STR41, Disp_41
  1758.         dw      4200h, STR42, Disp_42
  1759.         dw      4300h, STR43, Disp_43
  1760.         dw      4400h, STR44, Disp_44
  1761.         dw      4500h, STR45, Disp_45
  1762.         dw      4600h, STR46, Disp_46
  1763.         dw      4700h, STR47, Disp_47
  1764.         dw      4800h, STR48, Disp_48
  1765.         dw      4900h, STR49, Disp_49
  1766.         dw      4a00h, STR4a, Disp_4a
  1767.         dw      4b00h, STR4b, Disp_4b
  1768.         dw      4c00h, STR4c, Disp_4c
  1769.         dw      4d00h, STR4d, Disp_Str
  1770.         dw      4e00h, STR4e, Disp_4e
  1771.         dw      4f00h, STR4f, Disp_Str
  1772.         dw      5000h, STRUN, Disp_Str
  1773.         dw      5100h, STRUN, Disp_Str
  1774.         dw      5200h, STRUN, Disp_Str
  1775.         dw      5300h, STRUN, Disp_Str
  1776.         dw      5400h, STR54, Disp_Str
  1777.         dw      5500h, STRUN, Disp_Str
  1778.         dw      5600h, STR56, Disp_56
  1779.         dw      5700h, STR57, Disp_57
  1780.         dw      5800h, STRUN, Disp_Str
  1781.         dw      5900h, STR59, Disp_Str
  1782.         dw      5a00h, STR5a, Disp_5a
  1783.         dw      5b00h, STR5b, Disp_5b
  1784.         dw      5c00h, STR5c, Disp_5c
  1785.         dw      5d00h, STRUN, Disp_Str
  1786.         dw      5e00h, STRUN, Disp_Str
  1787.         dw      5f00h, STRUN, Disp_Str
  1788.         dw      6000h, STRUN, Disp_Str
  1789.         dw      6100h, STRUN, Disp_Str
  1790.         dw      6200h, STR62, Disp_Str
  1791. LENFC   EQU     $ - FCtbl
  1792.  
  1793. ;
  1794. ; The XX's are just place holders for help in alignment during debugging
  1795. ;
  1796. STR00   db      'Terminate Program'
  1797.         db      0
  1798.  
  1799. STR01   db      'Keyboard Input With Echo'
  1800.         db      0
  1801.  
  1802. STR02   db      'Output Character  Hex XX  ASCII X'
  1803.         db      0
  1804.  
  1805. STR03   db      'Serial Input'
  1806.         db      0
  1807.  
  1808. STR04   db      'Serial Output     Hex XX  ASCII X'
  1809.         db      0
  1810.  
  1811. STR05   db      'Printer Output    Hex XX  ASCII X'
  1812.         db      0
  1813.  
  1814. STR06   db      'Direct Console I/O - '
  1815.         db      0
  1816.  
  1817. STR06I  db      'Input Character'
  1818.         db      0
  1819.  
  1820. STR07   db      'Direct Console Input Without Echo'
  1821.         db      0
  1822.  
  1823. STR08   db      'Console Input Without Echo'
  1824.         db      0
  1825.  
  1826. STR09   db      'Display String -->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1827.         db      'XXXXXXXXXXXL'
  1828.         db      0
  1829.  
  1830. STR0a   db      'Buffered Keyboard Input To XXXX:XXXXH'
  1831.         db      0
  1832.  
  1833. STR0b   db      'Check Standard Input Status'
  1834.         db      0
  1835.  
  1836. STR0c   db      'Clear Keyboard and Do Function XXH'
  1837.         db      0
  1838.  
  1839. STR0d   db      'Reset Disk'
  1840.         db      0
  1841.  
  1842. STR0e   db      'Select Disk XXH'
  1843.         db      0
  1844.  
  1845. STR0f   db      'Open File Using FCB at XXXX:XXXXH'
  1846.         db      0
  1847.  
  1848. STR10   db      'Close File Using FCB at XXXX:XXXXH'
  1849.         db      0
  1850.  
  1851. STR11   db      'Search For First Matching File Using FCB at XXXX:XXXXH'
  1852.         db      0
  1853.  
  1854. STR12   db      'Search For Next Matching File Using FCB at XXXX:XXXXH'
  1855.         db      0
  1856.  
  1857. STR13   db      'Delete File Using FCB at XXXX:XXXXH'
  1858.         db      0
  1859.  
  1860. STR14   db      'Read Sequential File Record Using FCB at XXXX:XXXXH'
  1861.         db      0
  1862.  
  1863. STR15   db      'Write Sequential File Record Using FCB at XXXX:XXXXH'
  1864.         db      0
  1865.  
  1866. STR16   db      'Create File Using FCB at XXXX:XXXXH'
  1867.         db      0
  1868.  
  1869. STR17   db      'Rename File Using FCB at XXXX:XXXXH'
  1870.         db      0
  1871.  
  1872. STR19   db      'Report Current Drive'
  1873.         db      0
  1874.  
  1875. STR1a   db      'Set Disk Transfer Address To XXXX:XXXXH'
  1876.         db      0
  1877.  
  1878. STR1b   db      'Get FAT Information For Default Drive'
  1879.         db      0
  1880.  
  1881. STR1c   db      'Get FAT Information For Drive XXH'
  1882.         db      0
  1883.  
  1884. STR21   db      'Read Random File Record Using FCB at XXXX:XXXXH'
  1885.         db      0
  1886.  
  1887. STR22   db      'Write Random File Record Using FCB at XXXX:XXXXH'
  1888.         db      0
  1889.  
  1890. STR23   db      'Get File Size Using FCB at XXXX:XXXXH'
  1891.         db      0
  1892.  
  1893. STR24   db      'Set Random Record Field Using FCB at XXXX:XXXXH'
  1894.         db      0
  1895.  
  1896. STR25   db      'Set Interrupt Vector XXH to XXXX:XXXXH'
  1897.         db      0
  1898.  
  1899. STR26   db      'Create New Program Segment At Segment XXXXH'
  1900.         db      0
  1901.  
  1902. STR27   db      'Read XXXXH Random File Records Using FCB at XXXX:XXXXH'
  1903.         db      0
  1904.  
  1905. STR28   db      'Write XXXXH Random File Records Using FCB at XXXX:XXXXH'
  1906.         db      0
  1907.  
  1908. STR29   db      'Parse Filename -->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1909.         db      'XXXXXXXXXXXL'
  1910.         db      0
  1911.  
  1912. STR2a   db      'Get Date'
  1913.         db      0
  1914.  
  1915. STR2b   db      'Set Date To mm/dd/yy  XX/XX/XX'
  1916.         db      0
  1917.  
  1918. STR2c   db      'Get Time'
  1919.         db      0
  1920.  
  1921. STR2d   db      'Set Time To Hrs:Mins:Secs:Hunds  XX:XX:XX:XX'
  1922.         db      0
  1923.  
  1924. STR2e   db      'Set Disk Write Verification XXX'
  1925.         db      0
  1926.  
  1927. STR2f   db      'Get Disk Transfer Address'
  1928.         db      0
  1929.  
  1930. STR30   db      'Get DOS Version Number'
  1931.         db      0
  1932.  
  1933. STR31   db      'Terminate Process and Remain Resident'
  1934.         db      0
  1935.  
  1936. STR33   db      'Get/Set Control-Break Status'
  1937.         db      0
  1938.  
  1939. STR33G  db      'Get Control-Break Status'
  1940.         db      0
  1941.  
  1942. STR33S  db      'Set Control-Break Status XXX'
  1943.         db      0
  1944.  
  1945. STR35   db      'Get Interrupt Vector XXH'
  1946.         db      0
  1947.  
  1948. STR36   db      'Get Disk Free Space On Drive XXH'
  1949.         db      0
  1950.  
  1951. STR37   db      'Get DOS Switch Character'
  1952.         db      0
  1953.  
  1954. STR38   db      'Get/Set Country Dependent Information'
  1955.         db      0
  1956.  
  1957. STR39   db      'Create Subdir --->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1958.         db      'XXXXXXXXXXXL'
  1959.         db      0
  1960.  
  1961. STR3a   db      'Remove Subdir --->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1962.         db      'XXXXXXXXXXXL'
  1963.         db      0
  1964.  
  1965. STR3b   db      'Change Dir To --->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1966.         db      'XXXXXXXXXXXL'
  1967.         db      0
  1968.  
  1969. STR3c   db      'Create File ----->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1970.         db      'XXXXXXXXXXXL'
  1971.         db      0
  1972.  
  1973. STR3d   db      'Open File ------->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1974.         db      'XXXXXXXXXXXL'
  1975.         db      0
  1976.  
  1977. STR3e   db      'Close File Handle XXXXH'
  1978.         db      0
  1979.  
  1980. STR3f   db      'Read XXXXH Bytes From File or Device XXXXH'
  1981.         db      0
  1982.  
  1983. STR40   db      'Write XXXXH Bytes To File or Device XXXXH'
  1984.         db      0
  1985.  
  1986. STR41   db      'Delete File ----->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1987.         db      'XXXXXXXXXXXL'
  1988.         db      0
  1989.  
  1990. STR42   db      'Move File Handle XXXXH Pointer By XXXX:XXXXH From '
  1991.         db      'XXXXXXXXXXXXXXXXX'
  1992.         db      0
  1993.  
  1994. STR43   db      'Get/Set File Attributes'
  1995.         db      0
  1996.  
  1997. STR43G  db      'Get File Attrib ->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  1998.         db      'XXXXXXXXXXXX'
  1999.         db      0
  2000.  
  2001. STR43S  db      'Set File Attrib ->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  2002.         db      'XXXXXXXXXXXX'
  2003.         db      0
  2004.  
  2005. STR44   db      'I/O Control For Devices'
  2006.         db      0
  2007.  
  2008. STR440  db      'Get Info For Device XXXXH'
  2009.         db      0
  2010.  
  2011. STR441  db      'Set Info For Device XXXXH to XXXXH'
  2012.         db      0
  2013.  
  2014. STR442  db      'Read XXXXH Bytes From Drive Control Channel of File XXXXH'
  2015.         db      0
  2016.  
  2017. STR443  db      'Write XXXXH Bytes To Drive Control Channel of File XXXXH'
  2018.         db      0
  2019.  
  2020. STR444  db      'Read XXXXH Bytes From Control Channel of Drive XXH'
  2021.         db      0
  2022.  
  2023. STR445  db      'Write XXXXH Bytes To Control Channel of Drive XXH'
  2024.         db      0
  2025.  
  2026. STR446  db      'Get Input Status of Device XXXXH'
  2027.         db      0
  2028.  
  2029. STR447  db      'Get Output Status of Device XXXXH'
  2030.         db      0
  2031.  
  2032. STR448  db      'Report Whether Device XXXXH Has Removable Media'
  2033.         db      0
  2034.  
  2035. STR4411 db      'Set Retries For Device XXXXH to XXXXH With Interval of XXXXH'
  2036.         db      0
  2037.  
  2038. STR45   db      'Duplicate File Handle XXXXH'
  2039.         db      0
  2040.  
  2041. STR46   db      'Force Duplication of Handle XXXXH to XXXXH'
  2042.         db      0
  2043.  
  2044. STR47   db      'Get Current Directory of Drive XXH into XXXX:XXXXH'
  2045.         db      0
  2046.  
  2047. STR48   db      'Allocate XXXXH Paragraphs of Memory'
  2048.         db      0
  2049.  
  2050. STR49   db      'Free Allocated Memory at Segment XXXXH'
  2051.         db      0
  2052.  
  2053. STR4a   db      'Modify Memory Block at Segment XXXXH to be XXXXH Paragraphs'
  2054.         db      0
  2055.  
  2056. STR4b   db      'Load or Execute Program ---->XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  2057.         db      'XXXXXXXXXXXX'
  2058.         db      0
  2059.  
  2060. STR4c   db      'Terminate Process With Return Code XXH'
  2061.         db      0
  2062.  
  2063. STR4d   db      'Get Return Code of Subprocess'
  2064.         db      0
  2065.  
  2066. STR4e   db      'Find First Matching File --->XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  2067.         db      'XXXXXXXXXXXX'
  2068.         db      0
  2069.  
  2070. STR4f   db      'Find Next Matching File'
  2071.         db      0
  2072.  
  2073. STR54   db      'Get Verify State'
  2074.         db      0
  2075.  
  2076. STR56   db      'Rename File   Old Name ----->XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  2077.         db      'XXXXXXXXXXXX'
  2078.         db      0
  2079.  
  2080. STR56N  db      '              New Name ----->XXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  2081.         db      'XXXXXXXXXXXX'
  2082.         db      0
  2083.  
  2084. STR57   db      'Get/Set Date and Time of File Handle XXXXH'
  2085.         db      0
  2086.  
  2087. STR57G  db      'Get Date and Time of File Handle XXXXH'
  2088.         db      0
  2089.  
  2090. STR57S  db      'Set Date and Time of File Handle XXXXH'
  2091.         db      0
  2092.  
  2093. STR59   db      'Get Extended Error Code'
  2094.         db      0
  2095.  
  2096. STR5a   db      'Create Temp File->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  2097.         db      'XXXXXXXXXXXL'
  2098.         db      0
  2099.  
  2100. STR5b   db      'Create New File ->XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  2101.         db      'XXXXXXXXXXXL'
  2102.         db      0
  2103.  
  2104. STR5c   db      'Lock/Unlock File XXXXH'
  2105.         db      0
  2106.  
  2107. STR5c0  db      'Lock File XXXXH'
  2108.         db      0
  2109.  
  2110. STR5c1  db      'Unlock File XXXXH'
  2111.         db      0
  2112.  
  2113. STR62   db      'Get PSP Address'
  2114.         db      0
  2115.  
  2116. STRUN   db      '** Undocumented Function Code **'
  2117.         db      0
  2118.  
  2119. ;
  2120. ; Don't change the size of the following strings
  2121. ;
  2122. Blanks3  db      '   '
  2123. Blanks17 db      '                 '
  2124. ONstr    db      'ON '
  2125. OFFstr   db      'OFF'
  2126. BOFstr   db      'Beginning of File'
  2127. CURstr   db      'Current Location '
  2128. EOFstr   db      'End of File      '
  2129.  
  2130. RCStr   db      'Return Code = XXXXH'
  2131.         db      0
  2132.  
  2133. CFStr   db      'Carry Flag = X'
  2134.         db      0
  2135.  
  2136. ZFStr   db      'Zero Flag = X'
  2137.         db      0
  2138.  
  2139.  
  2140. Open_Window:
  2141.         push    BP
  2142.         push    ES
  2143. ;
  2144. ; Calculate current page offset each time since it can change at any time
  2145. ;
  2146.         mov     AH,0fh              ; get current video state
  2147.         int     10h
  2148.         mov     CL,BH               ; returns BH = active page #
  2149.         xor     CH,CH
  2150.         mov     AX,0100h            ; page length in paragraphs
  2151.         mul     cx
  2152.         add     AX,Scrseg           ; add base segment of screen
  2153.         mov     Pageseg,AX
  2154. ;
  2155. ; Save current contents of window area
  2156. ;
  2157.         mov     BX,OFFSET W1        ; window parameters
  2158.         mov     SI,[BX].startmem    ; screen addr of start of window
  2159.         mov     DX,[BX].height
  2160.         mov     ES,Winseg           ; point to allocated memory block
  2161.         mov     DI,0000
  2162. saverow:
  2163.         push    DS
  2164.         mov     CX,[BX].xwidth
  2165.         mov     DS,Pageseg          ; get screen segment
  2166.         push    SI                  ; save screen offset
  2167. rep     movsw                       ; do word to get char and attribute
  2168.         pop     SI
  2169.         pop     DS
  2170.         add     SI,BytesPL          ; next row down
  2171.         dec     DX
  2172.         jnz     saverow
  2173. ;
  2174. ; Draw window
  2175. ;
  2176.         mov     ES,Pageseg          ; get screen segment
  2177.         mov     DI,[BX].startmem    ; physical addr of start of window
  2178.         mov     AH,HIWHITE
  2179. ;
  2180. ; Draw top border
  2181. ;
  2182.         push    DI
  2183.         mov     AL,ULC              ; write upper left corner
  2184.         stosw
  2185.         mov     CX,[BX].xwidth
  2186.         sub     CX,2
  2187.         mov     AL,BRDROW
  2188. rep     stosw
  2189.         mov     AL,URC              ; write upper right corner
  2190.         stosw
  2191.         pop     DI
  2192.         add     DI,BytesPL          ; next row down
  2193. ;
  2194. ; Put version along top
  2195. ;
  2196.         push    AX                  ; save attribute
  2197.         push    DI                  ;  and scrren pointer for next row
  2198.         mov     CX,LENVER
  2199.         shr     CX,1                ; divide string length by 2
  2200.         mov     AX,[BX].xwidth
  2201.         shr     AX,1                ; divide window width by 2
  2202.         sub     AX,CX
  2203.         mov     DI,[BX].startmem
  2204.         shl     AX,1                ; difference times 2 for char + attr
  2205.         add     DI,AX
  2206.         mov     AH,74h              ; attribute for string (Red on White)
  2207.         mov     SI,OFFSET VERmsg
  2208.         mov     CX,LENVER
  2209. putver:
  2210.         lodsb
  2211.         stosw
  2212.         loop    putver
  2213.         pop     DI
  2214.         pop     AX
  2215. ;
  2216. ; Draw middle of window
  2217. ;
  2218.         mov     DX,[BX].height
  2219.         sub     DX,2
  2220. winrows:
  2221.         push    DI
  2222.         mov     AL,BRDCOL           ; left border column
  2223.         stosw
  2224.         mov     CX,[BX].xwidth
  2225.         sub     CX,2
  2226.         mov     AL,BLANK
  2227. rep     stosw
  2228.         mov     AL,BRDCOL           ; right border column
  2229.         stosw
  2230.         pop     DI
  2231.         add     DI,BytesPL          ; next row down
  2232.         dec     DX
  2233.         jnz     winrows
  2234. ;
  2235. ; Draw bottom border
  2236. ;
  2237.         push    DI
  2238.         mov     AL,LLC              ; write lower left corner
  2239.         stosw
  2240.         mov     CX,[BX].xwidth
  2241.         sub     CX,2
  2242.         mov     AL,BRDROW
  2243. rep     stosw
  2244.         mov     AL,LRC              ; write lower right corner
  2245.         stosw
  2246.         pop     DI
  2247. ;
  2248.         pop     ES
  2249.         pop     BP
  2250.         ret
  2251.  
  2252.  
  2253. Close_Window:
  2254.         push    ES
  2255.         mov     BX,OFFSET W1
  2256.         mov     DI,[BX].startmem    ; physical addr of screen area
  2257.         mov     ES,Pageseg          ; point to allocated memory block
  2258.         mov     SI,0000             ; start of save memory block
  2259.         mov     DX,[BX].height
  2260. resrow:
  2261.         push    DS
  2262.         mov     CX,[BX].xwidth
  2263.         mov     DS,Winseg           ; get saved memory segment
  2264.         push    DI                  ; save screen offset
  2265. rep     movsw                       ; do word to get char and attribute
  2266.         pop     DI
  2267.         pop     DS
  2268.         add     DI,BytesPL          ; next row down
  2269.         dec     DX
  2270.         jnz     resrow
  2271.         pop     ES
  2272.         ret
  2273.  
  2274. ;
  2275. ; Print a string in window.
  2276. ; Entry:
  2277. ;        CX = Row, Col position relative to start of window
  2278. ;        BX = Window pointer
  2279. ;        AH = Attribute
  2280. ;        DX = addr of string
  2281. ;
  2282. WPrint:
  2283.         push    ES
  2284.         call    GetRC               ; convert to row, col in DI
  2285.         mov     ES,Pageseg
  2286.         mov     SI,DX               ; move string address
  2287. wpwrt:
  2288.         cmp     BYTE PTR [SI],00    ; test for string terminator <NULL>
  2289.         jz      wpexit
  2290.         lodsb
  2291.         stosw
  2292.         jmp     wpwrt
  2293. wpexit:
  2294.         pop     ES
  2295.         ret
  2296.  
  2297. ;
  2298. ; Write one character and attribute to window
  2299. ;
  2300. ; Entry:
  2301. ;        CX = Row, Col position relative to start of window
  2302. ;        BX = Window pointer
  2303. ;        AH = attr
  2304. ;        AL = char
  2305. ;
  2306. WChar:
  2307.         push    ES
  2308.         call    GetRC               ; convert to row, col in DI
  2309.         mov     ES,Pageseg
  2310.         stosw
  2311.         pop     ES
  2312.         ret
  2313.  
  2314. ;
  2315. ; Convert row, col in CX to physical addr in DI
  2316. ;
  2317. GetRC:
  2318.         push    AX
  2319.         push    DX
  2320.         mov     DI,[BX].startmem    ; physical start of window memory
  2321.         add     DI,BytesPL          ; go down a row
  2322.         add     DI,2                ; go in one char, this is 0,0
  2323.         mov     AL,CH
  2324.         xor     AH,AH               ; AX = relative row number
  2325.         mul     BytesPL             ; this clobbers DX
  2326.         add     DI,AX
  2327.         mov     AX,CX               ; restore coordinates
  2328.         xor     AH,AH               ; AX = relative col number
  2329.         shl     AX,1                ; times 2 for attribute
  2330.         add     DI,AX
  2331.         pop     DX
  2332.         pop     AX
  2333.         ret
  2334.  
  2335. ;
  2336. ; WRITE HEX WORD
  2337. ; Convert a hex word to an ASCII string and display it
  2338. ; Entry:
  2339. ;        CX = Row, Col position relative to start of window
  2340. ;        BX = Window pointer
  2341. ;        AX = Word to convert
  2342. ;
  2343. Whexwd:
  2344.         push    AX
  2345.         push    BX
  2346.         push    CX
  2347.         push    DX
  2348. ;
  2349.         push    BX                  ; save window pointer
  2350.         push    CX                  ;  and row, col
  2351.         mov     DI,OFFSET Astr
  2352.         xchg    AH,AL
  2353.         call    Shexbyt
  2354.         xchg    AH,AL
  2355.         call    Shexbyt
  2356.         xor     AL,AL
  2357.         stosb                       ; make sure of terminating NULL
  2358.         mov     DX,OFFSET Astr
  2359.         pop     CX                  ; get row, col
  2360.         pop     BX                  ;  and Window ptr
  2361.         mov     AH,HIWHITE          ; set attribute
  2362.         call    WPrint
  2363. ;
  2364.         pop     DX
  2365.         pop     CX
  2366.         pop     BX
  2367.         pop     AX
  2368.         ret
  2369.  
  2370. ;
  2371. ; STORE HEX WORD
  2372. ; Convert a hex word to ASCII and store it in destination string
  2373. ; Entry:
  2374. ;        AX = Word to convert
  2375. ;        DI = destination pointer
  2376. ;
  2377. Shexwrd:
  2378.         xchg    AL,AH               ; convert upper half first
  2379.         call    Shexbyt
  2380.         xchg    AL,AH               ; convert lower half
  2381.         call    Shexbyt
  2382.         ret
  2383.  
  2384. ;
  2385. ; STORE HEX BYTE
  2386. ; Convert a hex byte to ASCII and store it in destination string
  2387. ; Entry:
  2388. ;        AL = Byte to convert
  2389. ;        DI = destination pointer
  2390. ;
  2391. Shexbyt:
  2392.         push    AX
  2393.         mov     AH,AL               ; save temporarily
  2394.         shr     AL,1
  2395.         shr     AL,1
  2396.         shr     AL,1
  2397.         shr     AL,1
  2398.         cmp     AL,10
  2399.         jb      wh1
  2400.         add     AL,07
  2401. wh1:
  2402.         add     AL,'0'
  2403.         stosb
  2404.         mov     AL,AH
  2405.         and     AL,0fh
  2406.         cmp     AL,10
  2407.         jb      wh2
  2408.         add     AL,07
  2409. wh2:
  2410.         add     AL,'0'
  2411.         stosb
  2412.         pop     AX
  2413.         ret
  2414.  
  2415. ;
  2416. ; Check if key pressed requires special handling
  2417. ;
  2418. ; Entry:
  2419. ;      AX = key pressed
  2420. ;
  2421. Disp_Key:
  2422.         mov     DI,OFFSET Keytbl    ; keys and subroutine addresses
  2423.         mov     CX,LENKTAB / 4      ; number of entries
  2424. cmpdk:
  2425.         cmp     AX,[DI]             ; is key in table?
  2426.         jz      dkexec
  2427.         add     DI,4                ; no, point to next key value
  2428.         loop    cmpdk
  2429.         clc                         ; carry clear means exit upon return
  2430.         ret
  2431. dkexec:
  2432.         add     DI,2
  2433.         call    [WORD PTR DI]
  2434.         ret
  2435.  
  2436. ;
  2437. ; Table of keys to watch for followed by the address of the routine to execute
  2438. ;
  2439. Keytbl  dw      ESCAPE,     DO_Esc
  2440.         dw      BIGS,       Do_Skey
  2441.         dw      SMALLS,     Do_Skey
  2442.         dw      BIGR,       Do_Rkey
  2443.         dw      SMALLR,     Do_Rkey
  2444.         dw      UPARROW,    Do_Up
  2445.         dw      DOWNARROW,  Do_Down
  2446.         dw      LEFTARROW,  Do_Left
  2447.         dw      RIGHTARROW, Do_Right
  2448.         dw      HOME,       Do_Home
  2449.         dw      XEND,       Do_End
  2450.         dw      PGUP,       Do_Pgup
  2451.         dw      PGDN,       Do_Pgdn
  2452. LENKTAB EQU     $ - Keytbl
  2453.  
  2454. ;
  2455. ; If ESC key, clear 'running flag' so Int 21h will not be stopped each time
  2456. ;
  2457. Do_Esc:
  2458.         mov     AL,00
  2459.         mov     Run_Flg,AL
  2460.         clc                         ; carry clear means exit upon return
  2461.         ret
  2462.  
  2463. ;
  2464. ; 'S' key - skip successive functions of current type.
  2465. ; Return to intercepting calls when something new comes along.
  2466. ; This is so you don't have to sit through dozens if Function '2' calls
  2467. ; while the target program outputs a string to the display.
  2468. ;
  2469. Do_Skey:
  2470.         mov     AL,0ffh
  2471.         mov     Skip_Flg,AL         ; set flag to show we should skip something
  2472.         mov     AX,AXsave           ; get current function code
  2473.         mov     Skip_Typ,AH         ; save it
  2474.         clc                         ; carry clear means exit upon return
  2475.         ret
  2476.  
  2477. ;
  2478. ; 'R' key - stop after INT 21h call and let user see result registers
  2479. ;
  2480. Do_Rkey:
  2481.         mov     AL,0ffh
  2482.         mov     Ret_Flg,AL          ; set flag
  2483.         clc                         ; carry clear means exit upon return
  2484.         ret
  2485.  
  2486. ;
  2487. ; DO_Up - move window up one line
  2488. ;
  2489. Do_Up:
  2490.         mov     BX,OFFSET W1
  2491.         call    Close_Window
  2492.         mov     AX,[BX].leftrow
  2493.         or      AX,AX               ; already at top of screen?
  2494.         jz      upexit
  2495.         dec     [BX].leftrow
  2496.         dec     [BX].rightrow
  2497.         call    Window_Parms        ; recalculate parameters
  2498. upexit:
  2499.         stc                         ; don't exit upon return
  2500.         ret
  2501.  
  2502. ;
  2503. ; DO_Down - move window down one line
  2504. ;
  2505. Do_Down:
  2506.         mov     BX,OFFSET W1
  2507.         call    Close_Window
  2508.         mov     AX,[BX].rightrow
  2509.         cmp     AX,24               ; already at bottom of screen?
  2510.         jz      dnexit
  2511.         inc     [BX].leftrow
  2512.         inc     [BX].rightrow
  2513.         call    Window_Parms        ; recalculate parameters
  2514. dnexit:
  2515.         stc                         ; don't exit upon return
  2516.         ret
  2517.  
  2518. ;
  2519. ; DO_Left - move window left one column
  2520. ;
  2521. Do_Left:
  2522.         mov     BX,OFFSET W1
  2523.         call    Close_Window
  2524.         mov     AX,[BX].leftcol
  2525.         or      AX,AX               ; already at left of screen?
  2526.         jz      lfexit
  2527.         dec     [BX].leftcol
  2528.         dec     [BX].rightcol
  2529.         call    Window_Parms        ; recalculate parameters
  2530. lfexit:
  2531.         stc                         ; don't exit upon return
  2532.         ret
  2533.  
  2534. ;
  2535. ; DO_right - move window right one column
  2536. ;
  2537. Do_Right:
  2538.         mov     BX,OFFSET W1
  2539.         call    Close_Window
  2540.         mov     AX,[BX].rightcol
  2541.         cmp     AX,79               ; already at right of screen?
  2542.         jz      rtexit
  2543.         inc     [BX].leftcol
  2544.         inc     [BX].rightcol
  2545.         call    Window_Parms        ; recalculate parameters
  2546. rtexit:
  2547.         stc                         ; don't exit upon return
  2548.         ret
  2549.  
  2550. ;
  2551. ; Do_Home - move window to upper left corner
  2552. ;
  2553. Do_Home:
  2554.         mov     BX,OFFSET W1
  2555.         call    Close_Window
  2556.         xor     AX,AX
  2557.         mov     [BX].leftrow,AX
  2558.         mov     [BX].leftcol,AX
  2559. ;
  2560.         mov     AX,[BX].leftrow
  2561.         add     AX,[BX].height
  2562.         dec     AX
  2563.         mov     [BX].rightrow,AX
  2564. ;
  2565.         mov     AX,[BX].leftcol
  2566.         add     AX,[BX].xwidth
  2567.         dec     AX
  2568.         mov     [BX].rightcol,AX
  2569. ;
  2570.         call    Window_Parms        ; recalculate parameters
  2571.         stc                         ; don't exit upon return
  2572.         ret
  2573.  
  2574. ;
  2575. ; Do_End - move window to lower left corner
  2576. ;
  2577. Do_End:
  2578.         mov     BX,OFFSET W1
  2579.         call    Close_Window
  2580.         mov     AX,24
  2581.         mov     [BX].rightrow,AX
  2582.         xor     AX,AX
  2583.         mov     [BX].leftcol,AX
  2584. ;
  2585.         mov     AX,[BX].rightrow
  2586.         sub     AX,[BX].height
  2587.         inc     AX
  2588.         mov     [BX].leftrow,AX
  2589. ;
  2590.         mov     AX,[BX].leftcol
  2591.         add     AX,[BX].xwidth
  2592.         dec     AX
  2593.         mov     [BX].rightcol,AX
  2594. ;
  2595.         call    Window_Parms        ; recalculate parameters
  2596.         stc                         ; don't exit upon return
  2597.         ret
  2598.  
  2599. ;
  2600. ; Do_Pgup - move window to upper right corner
  2601. ;
  2602. Do_Pgup:
  2603.         mov     BX,OFFSET W1
  2604.         call    Close_Window
  2605.         xor     AX,AX
  2606.         mov     [BX].leftrow,AX
  2607.         mov     AX,79
  2608.         mov     [BX].rightcol,AX
  2609. ;
  2610.         mov     AX,[BX].leftrow
  2611.         add     AX,[BX].height
  2612.         dec     AX
  2613.         mov     [BX].rightrow,AX
  2614. ;
  2615.         mov     AX,[BX].rightcol
  2616.         sub     AX,[BX].xwidth
  2617.         inc     AX
  2618.         mov     [BX].leftcol,AX
  2619. ;
  2620.         call    Window_Parms        ; recalculate parameters
  2621.         stc                         ; don't exit upon return
  2622.         ret
  2623.  
  2624. ;
  2625. ; Do_Pgdn - move window to lower right corner
  2626. ;
  2627. Do_Pgdn:
  2628.         mov     BX,OFFSET W1
  2629.         call    Close_Window
  2630.         mov     AX,24
  2631.         mov     [BX].rightrow,AX
  2632.         mov     AX,79
  2633.         mov     [BX].rightcol,AX
  2634. ;
  2635.         mov     AX,[BX].rightrow
  2636.         sub     AX,[BX].height
  2637.         inc     AX
  2638.         mov     [BX].leftrow,AX
  2639. ;
  2640.         mov     AX,[BX].rightcol
  2641.         sub     AX,[BX].xwidth
  2642.         inc     AX
  2643.         mov     [BX].leftcol,AX
  2644. ;
  2645.         call    Window_Parms        ; recalculate parameters
  2646.         stc                         ; don't exit upon return
  2647.         ret
  2648.  
  2649. ;
  2650. ; Wait for any key pressed
  2651. ;
  2652. Get_Key:
  2653.         push    BP                  ; just in case
  2654.         mov     AH,00
  2655.         int     16h
  2656.         pop     BP
  2657.         ret
  2658.  
  2659. ;
  2660. ; Calculate window parameters:
  2661. ;      1) Physical starting address of window
  2662. ;      2) Width of window in characters
  2663. ;      3) Height of window
  2664. ;
  2665. ; Entry:
  2666. ;      BX = window pointer
  2667. ; Exit:
  2668. ;      AX = Number of bytes contained in window
  2669. ;
  2670. Window_Parms:
  2671.         mov     AX,[BX].leftrow
  2672.         mul     BytesPL             ; multiply by bytes per line
  2673.         mov     CX,[BX].leftcol
  2674.         shl     CX,1                ; times 2 for attribute byte
  2675.         add     AX,CX
  2676.         mov     SI,AX               ; starting physical address of window
  2677.         mov     [BX].startmem,AX    ; save it for later
  2678. ;
  2679. ; Calculate size of window in bytes to allocate memory
  2680. ;
  2681.         mov     AX,[BX].rightcol
  2682.         inc     AX
  2683.         sub     AX,[BX].leftcol
  2684.         mov     [BX].xwidth,AX
  2685.         mov     CX,[BX].rightrow
  2686.         inc     CX
  2687.         sub     CX,[BX].leftrow
  2688.         mov     [BX].height,CX
  2689.         mul     CL                  ; AX = nbr of bytes of screen area
  2690.         shl     AX,1                ; times 2 to get attributes also
  2691.         ret
  2692.  
  2693. ;
  2694. ; Define format of WINDOW structure
  2695. ;
  2696. Window  STRUC
  2697.    leftrow   dw     ?
  2698.    leftcol   dw     ?
  2699.    rightrow  dw     ?
  2700.    rightcol  dw     ?
  2701.    xwidth    dw     ?
  2702.    height    dw     ?
  2703.    startmem  dw     ?
  2704. Window  ENDS
  2705.  
  2706. ;
  2707. ; Allocate and initialize WINDOW parameters
  2708. ;
  2709. W1       Window     <8, 2, 18, 74, 0, 0, 0>
  2710.  
  2711. Winseg    dw     0000                ; store segment of allocated memory
  2712.                                      ;  for saving screen data
  2713. Scrseg    dw     0000                ; base segment for screen memory
  2714. Pageseg   dw     0000                ; segment after page offset factored in
  2715. BytesPL   dw     80*2                ; number of bytes per line (char + attr)
  2716. Run_Flg   db     0ffh                ; 'running' flag
  2717. Ret_Flg   db     00                  ; 'stop on return' flag
  2718. Sw_Char   db     '/'                 ; DOS switch character
  2719. ;
  2720. ; The following two variables are initialized the way they are to skip
  2721. ; the first Int 21 call generated by 'STEPDOS' to EXEC the target program.
  2722. ;
  2723. Skip_Typ db     4bh                 ; type of function call to skip temporarily
  2724. Skip_Flg db     0ffh                ; set if function should be skipped
  2725.  
  2726. Save21   dw     ?                   ; save original Int21 vector here, IP
  2727.          dw     ?                   ;  and SEG
  2728.  
  2729. Ssave    LABEL  DWORD
  2730. SPsave   dw     ?                   ; save some of the user's registers here
  2731. SSsave   dw     ?                   ;  others will be on local stack
  2732.  
  2733. AXsave   dw     ?                   ; these will have been left on user's
  2734. DSsave   dw     ?                   ;  stack instead of local stack
  2735. CSsave   dw     ?
  2736. IPsave   dw     ?
  2737. FLsave   dw     ?
  2738. ;
  2739. ; Parameter block that will be passed to the EXEC function call (4bh) of DOS
  2740. ;
  2741. Param_Block     LABEL  WORD
  2742. SegEnv   dw     ?                   ; segment addr of environment string
  2743. SegCmd   dw     ?                   ; segmented ptr to command line
  2744.          dw     ?
  2745. FCBptr1  dw     ?                   ; segmented ptr to first FCB
  2746.          dw     ?
  2747. FCBptr2  dw     ?                   ; segmented ptr to second FCB
  2748.          dw     ?
  2749.  
  2750. ;
  2751. ; File name that will be passed to the EXEC function call of DOS
  2752. ;
  2753. Filename db     128 dup (0)
  2754. FNsize   dw     0
  2755. ;
  2756. ; Command line from PSP:80h will be copied here to work from
  2757. ;
  2758. PSPstr   db     128 dup (0)
  2759.  
  2760. ;
  2761. ; Command Line that will be passed to the EXEC function call of DOS
  2762. ;
  2763. CLstr    db     128 dup (0)
  2764.  
  2765. ;
  2766. ; Two FCB's that will be passed to the EXEC function call of DOS
  2767. ;
  2768. FCB1     db     0
  2769.          db     11 dup (' ')
  2770.          db     0, 0, 0, 0
  2771.  
  2772. FCB2     db     0
  2773.          db     11 dup (' ')
  2774.          db     0, 0, 0, 0
  2775.  
  2776. COMstr  db      '.COM'
  2777. EXEstr  db      '.EXE'
  2778. ;
  2779. VERmsg   db     ' STEPDOS Version 1.2 '
  2780. LENVER   EQU    $ - VERmsg
  2781.  
  2782. Memerr   db     CR
  2783.          db     LF
  2784.          db     'Error Allocating Window Memory$'
  2785.  
  2786. Execmsg  db     CR
  2787.          db     LF
  2788.          db     'Unable to execute target program$'
  2789.  
  2790. Findmsg  db     CR
  2791.          db     LF
  2792.          db     'Unable to find target program '
  2793.          db     27h                 ; opening quote
  2794.          db     '$'
  2795.  
  2796. Umsg     db     CR
  2797.          db     LF
  2798.          db     'Usage: STEPDOS filename$'
  2799.  
  2800. RegStr1  db     ' AX   BX   CX   DX   DI   SI   BP   SP'
  2801.          db     '   DS   ES   SS   CS   IP   FL'
  2802.          db     0
  2803.  
  2804. RegStr2  db     '---- ---- ---- ---- ---- ---- ---- ----'
  2805.          db     ' ---- ---- ---- ---- ---- ----'
  2806.          db     0
  2807.  
  2808. HlpStr1  db     'kip Current Func'
  2809.          db     0
  2810.  
  2811. HlpStr2  db     'eturn Code'
  2812.          db     0
  2813.  
  2814. HlpStr3  db     ' - Non Stop'
  2815.          db     0
  2816.  
  2817. HlpStr4  db     ' - Move Window'
  2818.          db     0
  2819.  
  2820. HlpStr5  db     'Press Any Key To Continue'
  2821.          db     0
  2822.  
  2823. Astr     db     32 dup (0)          ; string for converting ASCII characters
  2824.  
  2825. ;
  2826. ; Local Program Stack Area
  2827. ;
  2828.          db     128 dup (?)
  2829. Pstack   EQU    $
  2830.  
  2831. ;
  2832. ; Target Stack Area
  2833. ;
  2834.          db     128 dup (?)
  2835. Tstack   EQU    $
  2836.  
  2837.  
  2838. IF TESTING
  2839.  
  2840. Istr     db     128 dup (' ')
  2841.  
  2842. Ostr     db     'Output String'
  2843.          db     0
  2844. ENDIF
  2845.  
  2846.  
  2847. PRSIZE  EQU     $
  2848.  
  2849. Code    ENDS
  2850.  
  2851.         END     Main
  2852.  
  2853.